package com.cqrt.aop;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.cqrt.constant.RTErrorCodeEnum;
import com.cqrt.mapper.SaveTableTreeExtNewMapper;
import com.cqrt.vo.SaveTableTreeExtNewVO;
import com.hustcad.plm.rpm.model.dto.active.BatchSavePlanActiveDTO;
import com.hustcad.plm.rpm.model.dto.active.PlusTaskSaveDTO;
import com.hustcad.plm.rpm.model.dto.message.ObjectMsgTempLinkDTO;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

import static io.seata.common.util.LambdaUtils.distinctByKey;

@Aspect
@Component
@Slf4j
public class SaveTableTreeExtNewAop {

    @Resource
    private SaveTableTreeExtNewMapper saveTableTreeExtNewMapper;

    @Around(value = "execution(* com.hustcad.plm.rpm.controller.plan.PlanActiveController.saveTableTreeExtNew(..))")
    public Object saveTableTreeExtNew(ProceedingJoinPoint point) throws Throwable {
        BatchSavePlanActiveDTO requestParam=(BatchSavePlanActiveDTO)point.getArgs()[0];
        List<PlusTaskSaveDTO> data = requestParam.getData();
        String planOid = requestParam.getPlanOid();

        String templateId=saveTableTreeExtNewMapper.selectTemplateIdByActivteId(planOid);

        if (StrUtil.isBlank(templateId)){
            return point.proceed();
        }
//        List<SaveTableTreeExtNewVO> list = saveTableTreeExtNewMapper.selectAllActivteByPlanId(
//                templateId);
        List<SaveTableTreeExtNewVO> list = new ArrayList<>();
        //合体
        List<SaveTableTreeExtNewVO> saveTableTreeExtNewVOS = saveTableTreeExtNewMapper.selectAllActivteByPlanId(
                planOid);
        for (PlusTaskSaveDTO plusTaskSaveDTO:data){
//            String name = plusTaskSaveDTO.getName();
//            Optional<SaveTableTreeExtNewVO> any = saveTableTreeExtNewVOS.stream().filter(f -> name.equals(f.getName()))
//                    .findAny();
//            if (!any.isPresent()){
//                SaveTableTreeExtNewVO saveTableTreeExtNewVO = new SaveTableTreeExtNewVO();
//                saveTableTreeExtNewVO.setName(plusTaskSaveDTO.getName());
//                saveTableTreeExtNewVO.setOutLineLevel(Integer.parseInt(plusTaskSaveDTO.getOutLineLevel()));
//                saveTableTreeExtNewVO.setOutLineNumber(plusTaskSaveDTO.getOutLineNumber());
//                saveTableTreeExtNewVOS.add(saveTableTreeExtNewVO);
//            }
            SaveTableTreeExtNewVO saveTableTreeExtNewVO = new SaveTableTreeExtNewVO();
            saveTableTreeExtNewVO.setName(plusTaskSaveDTO.getName());
            saveTableTreeExtNewVO.setOutLineLevel(Integer.parseInt(plusTaskSaveDTO.getOutLineLevel()));
            saveTableTreeExtNewVO.setOutLineNumber(plusTaskSaveDTO.getOutLineNumber());
            saveTableTreeExtNewVOS.add(saveTableTreeExtNewVO);
        }
        list = list.stream()
                .filter(distinctByKey(SaveTableTreeExtNewVO::getName))
                .collect(Collectors.toList());
        //排序
        saveTableTreeExtNewVOS.sort((x,y)->{
            if (!x.getOutLineLevel().equals(y.getOutLineLevel())){

                return x.getOutLineNumber().compareTo(y.getOutLineNumber());
            }
            return x.getOutLineLevel().compareTo(y.getOutLineLevel());

        });


        //比较
        if (CollUtil.isNotEmpty(list) && CollUtil.isNotEmpty(saveTableTreeExtNewVOS)){
            if (list.size() == saveTableTreeExtNewVOS.size()){
                for (int i = 0; i < list.size(); i++) {
                    String name = list.get(i).getName();
                    Optional<SaveTableTreeExtNewVO> any = saveTableTreeExtNewVOS.stream().filter(
                            f -> f.getName().equals(name)).findAny();
                    if (!any.isPresent()){
                        throw RTErrorCodeEnum.ERR_NAME.getException("提交的计划名称未与计划模板名称标准化");
                    }
                }
            }else {
                throw RTErrorCodeEnum.ERR_NAME.getException("提交的计划名称未与计划模板名称标准化");
            }
        }
        return point.proceed();
    }

    @Before(value = "execution(* com.hustcad.plm.rpm.service.plan.TyppmGanttChartService.saveTableTreeEx(..))")
    public void checkPlanNotice(JoinPoint point) {
        List<PlusTaskSaveDTO> data = (List<PlusTaskSaveDTO>)point.getArgs()[1];
        Set<String> jobNames = new HashSet<>();
        for (PlusTaskSaveDTO datum : data) {
            if(Objects.isNull(datum)){
                continue;
            }
            List<ObjectMsgTempLinkDTO> noticeMessage = datum.getNoticeMessage();
            if(CollUtil.isNotEmpty(noticeMessage)){
                Map<String, List<ObjectMsgTempLinkDTO>> collect = noticeMessage.stream().collect(
                        Collectors.groupingBy(ObjectMsgTempLinkDTO::getTemplateOid));
                for (Map.Entry<String, List<ObjectMsgTempLinkDTO>> entry : collect.entrySet()) {
                    List<ObjectMsgTempLinkDTO> value = entry.getValue();
                    if(value.size()>1){
                        jobNames.add(datum.getName());
                        break;
                    }
                }
            }
        }
        if(!jobNames.isEmpty()){
            throw RTErrorCodeEnum.UPDATA_PROJECT_MANAGER_ERROR.getException("以下任务存在相同的通知事件:"+String.join(",",jobNames));
        }
    }
}
